package collection;

import java.util.HashMap;

/**
 * HashMap底层机制
 */
public class HashMapSource {

    public static void main(String[] args) {

        /*
            HashMap小结

            Map接口的常用实现类：HashMap Hashtable Properties
            HashMap 是以 Map 接口使用频率最高的实现类
            HashMap 是以 key-val 对的方式来存储数据(HashMap$Node)
            key 不能重复，但是值可以重复，允许使用null键和null值
            如果添加相同的 key 则会覆盖原来的 k-v 等同于修改
            与 HashSet 一样，不保证映射的顺序，底层是 数组 链表 红黑树实现
            HashMap没有实现同步，是线程不安全的
         */

        /*
            1) (k,v)是一个Node 实现了 Map.Entry<K,V>
            2)jdk7.0 hashmap 底层实现：数组 + 链表
         */

        /*
            扩容机制(同HashSet)
            1)底层维护了Node类型的数组table，默认为null
            2)当创建对象时，将加载因子(loadfactor)初始化为 0.75
            3)当添加key-val时，通过key的哈希值得到在table的索引。然后判断该索引处是否有元素
              如果没有元素直接添加。如果该索引处有元素，继续判断该元素的key和准备加入的key是否相等
              如果相等，直接替换val。如果不相等需要判断是树结构还是链表结构，做出相应处理。
              如果添加时发现容量不够，则需要扩容
            4)第一次添加，则需要扩容table容量为16，临界值(threshold)为16*0.75 = 12
            5)以后再扩容，则需要扩容table容量为原来的2倍，临界值为原来的2倍即24 以此类推
            6)在java8中，如果一条链表的元素个数超过TREEIFY_THRESHOLD(8),并且table的大小 >= MIN_TREEIRY_CAPACITY(64),就会进行树化
         */

        HashMap hashMap = new HashMap();
        for (int i = 0; i <= 12; i++) {
            hashMap.put(i, "hello");
        }

        hashMap.put("aaa", "bbb");

        System.out.println("hashmap = " + hashMap);

        //0-> 16(12)-> 32(24)-> 64(64*0.75=48)-> 128 (96)->
    }
}
